import hildon
import gtk
from imagehandling import Conversion, ImageHandling
import Image
from main_menu import MainMenu
from effects_menu import EffectsMenu
from transform_menu import TransformMenu
from share_menu import ShareMenu
from basewindow import BaseWindow
from limited_stack import LimitedStack
from text_dialog import TextDialog

class ImageEditor(BaseWindow):
    def __init__(self, program, widgets):
        BaseWindow.__init__(self, program, widgets, 'EditorWindow', 'Editor:Vbox', 'Editor:Menubar')
        
        # Store references to local vars.
        self.image_widget = widgets.get_widget('Editor:Image')
        self.main_vbox = widgets.get_widget('Editor:MainVbox')
        self.effects_vbox = widgets.get_widget('Editor:EffectsVbox')
        self.transform_vbox = widgets.get_widget('Editor:TransformVbox')
        self.share_vbox = widgets.get_widget('Editor:ShareVbox')
        self.spinner_vbox = widgets.get_widget('Editor:SpinnerVbox')
        self.undo_stack = LimitedStack(5)
        
        # Create button menus.
        self.main_menu = MainMenu(program, self, widgets)
        self.effects_menu = EffectsMenu(self, widgets)
        self.transform_menu = TransformMenu(self, widgets)
        self.share_menu = ShareMenu(self, widgets)

        # Attach menu item callbacks.
        quit_menuitem = widgets.get_widget('Editor:QuitMenuitem')
        quit_menuitem.connect('activate', gtk.main_quit)
        saveas_menuitem = widgets.get_widget('Editor:SaveAsMenuitem')
        saveas_menuitem.connect('activate', self.main_menu.save_button_clicked)
        settingsmenuitem = widgets.get_widget('Editor:SettingsMenuitem')
        settingsmenuitem.connect('activate', self.program.image_browser.menu_settings_activated)

        # Create the spinner for the spinner vbox.
        animation = gtk.gdk.PixbufAnimation('progress_spinner.gif')
        image = widgets.get_widget('Editor:SpinnerImage')
        image.set_from_animation(animation)

        # Set the initial mode of the window.
        self.__set_windowed_mode()
                
    def add_operation(self, operation):
        self.pending_operations.append(operation)
        
    def undo_operation(self):
        if len(self.pending_operations) != 0:            
            # Recreate the view. First try to obtain the previous image from the 
            # undo stack.
            if not self.undo_stack.empty():
                self.set_view_image(self.undo_stack.pop(), False)
                # Pop the last operation from the stack.
                self.pending_operations.pop()
            else:  
                # There was nothing in the undo stack. Notify the user.
                TextDialog("Error", "No further undo information available.").do_it()
    
    def view_update_callback(self, valid, new_image):
        # Display the new image if valid.
        if valid:
            self.set_view_image(new_image)
        else:
            print "Error doing preview op: %s"%new_image.message
            self.pending_operations.pop()
            
        # Switch to the main menu.
        self.spinner_vbox.hide()
        self.main_vbox.show()
    
    def set_view_image(self, image, undo = True):
        if undo:
            self.undo_stack.push(self.view_image)
        self.view_image = image
        self.image_widget.set_from_pixbuf(Conversion.image2pixbuf(self.view_image))
    
    def show(self, original_image):
        self.pending_operations = []
        self.undo_stack.clear()
        self.original_image = original_image
        if self.fullscreen != self.program.fullscreen:
            self.toggle_fullscreen()
        self.view_image = ImageHandling.simple_scale(self.original_image, self.width, self.height)
        self.image_widget.set_from_pixbuf(Conversion.image2pixbuf(self.view_image))
        self.window.show()
    
    def hide(self):
        self.program.fullscreen = self.fullscreen
        self.image_widget.clear()
        self.window.hide()
    
    def fullscreen_key_clicked(self):
        self.toggle_fullscreen()
        
    def __set_fullscreen_mode(self):
        self.fullscreen = True
        self.window.fullscreen()
        self.height = 480
        self.width = 660
        
    def __set_windowed_mode(self):
        self.fullscreen = False
        self.window.unfullscreen()
        self.height = 396
        self.width = 556

    def toggle_fullscreen(self):
        """
        Switches between fullscreen and windowed mode.
        """
        # Toggle between fullscreen and windowed mode.
        if self.fullscreen:
            self.__set_windowed_mode()
        else:
            self.__set_fullscreen_mode()
    
        # Resize the image currently displayed.
        self.view_image = ImageHandling.simple_scale(self.original_image, self.width, self.height)
        self.image_widget.set_from_pixbuf(Conversion.image2pixbuf(self.view_image))
